/*
 * @Author       : HONGKELI lihongkje@outlook.com
 * @Date         : 2024-04-24 09:40:44
 * @LastEditors  : HONGKELI lihongkje@outlook.com
 * @LastEditTime : 2024-04-25 10:00:11
 * @FilePath     : /EngMath/include/EngMath/Models/Vector3d.h
 * @Description  : 
 */

#ifndef VECTOR3D_H
#define VECTOR3D_H


#if defined(_WIN32) || defined(_WIN64)
#define PLATFORM_WINDOWS
#elif defined(__APPLE__) || defined(__MACH__)
#define PLATFORM_MAC
#elif defined(__linux__)
#define PLATFORM_LINUX
#endif

#include <cmath>

#include <EngMath/EngMath_glob.h>

namespace EM{

/*
 * Vector3d class
 * Represents a vector or a point in a three-dimensional space.
 * A Vector3d is defined by three coordinates: x, y, and z.
 * These coordinates can represent either a point in space 
 * (when the vector is considered as a position vector),
 * or they can represent the three components of a vector 
 * (when the vector is considered as a free vector).
 * This class allows for basic vector operations, such as addition, subtraction, scalar multiplication, and dot product.
 */
class ENGMATH_API Vector3d
{
public:
    Vector3d(double x = 0, double y = 0, double z = 0) : x(x), y(y), z(z) {}      // construct
    Vector3d(const Vector3d& other) : x(other.x), y(other.y), z(other.z)  {}      // copy construct
    Vector3d(Vector3d&& other) noexcept : x(other.x), y(other.y), z(other.z)      // move construct
    {
        other.x = 0;
        other.y = 0;
        other.z = 0;
    }
      
public:
    double x, y, z;    

public:
    // 向量加法
    Vector3d operator+(const Vector3d& other) const
    {
        return Vector3d(x + other.x, y + other.y, z + other.z);
    }

    // 向量减法
    Vector3d operator-(const Vector3d& other) const
    {
        return Vector3d(x - other.x, y - other.y, z - other.z);
    }

    // 标量乘法
    Vector3d operator*(double scalar) const
    {
        return Vector3d(x * scalar, y * scalar, z * scalar);
    }

    // 点积
    double dot(const Vector3d& other) const
    {
        return x * other.x + y * other.y + z * other.z;
    }

    // 叉积
    Vector3d cross(const Vector3d& other) const
    {
        return Vector3d(
            y * other.z - z * other.y,
            z * other.x - x * other.z,
            x * other.y - y * other.x);
    }

    // 模
    double norm() const {
        return sqrt(x*x + y*y + z*z);
    }
};

}

# endif